// 10.1 泛型算法概述
/**
 * 大多数算法都定义在头文件algorithm中。标准库还在头文件numeric中定义了一组数值泛型算法。
 */

#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::begin, std::end, std::find;
using std::cin, std::cout, std::endl;

int main()
{
    // 通常情况下，算法遍历范围，对其中每个元素进行一些处理。
    // 例如，假定我们有一个int的vector，希望知道vector中是否包含一个特定值。回答这个问题最方便的方法是调用标准库算法find：[插图]
    int val = 42; // 我们将查找的值
    vector<int> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto result = find(vec.cbegin(), vec.cend(), val);
    cout << "The value " << val << (result == vec.cend() ? " is not present" : " is present") << endl;

    // 类似的，由于指针就像内置数组上的迭代器一样，我们可以用find在数组中查找值：[插图]
    int ia[] = {22, 33, 44, 55, 66, 77, 88};
    int val1 = 83;
    int *result1 = find(begin(ia), end(ia), val1);

    // 还可以在序列的子范围中查找，只需将指向子范围首元素和尾元素之后位置的迭代器（指针）传递给find。
    // 例如，下面的语句在ia[1]、ia[2]和ia[3]中查找给定元素：[插图]
    auto result2 = find(ia + 1, ia + 4, val1); // 查找范围不包括ia[4]

    // 迭代器令算法不依赖于容器
    // 但算法依赖于元素类型的操作

    // 关键概念：算法永远不会执行容器的操作.泛型算法本身不会执行容器的操作，它们只会运行于迭代器之上，执行迭代器的操作。
    // 泛型算法运行于迭代器之上而不会执行容器操作的特性带来了一个令人惊讶但非常必要的编程假定：算法永远不会改变底层容器的大小。
    // 算法可能改变容器中保存的元素的值，也可能在容器内移动元素，但永远不会直接添加或删除元素。

    return 0;
}